package com.jhgsys.internal.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jhgsys.internal.common.constant.DictCodeConstant;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.utils.MD5Util;
import com.jhgsys.internal.dict.entity.DictItem;
import com.jhgsys.internal.dict.service.IDictService;
import com.jhgsys.internal.system.dto.UserDto;
import com.jhgsys.internal.system.entity.Dept;
import com.jhgsys.internal.system.entity.Role;
import com.jhgsys.internal.system.entity.User;
import com.jhgsys.internal.system.entity.UserRole;
import com.jhgsys.internal.system.mapper.UserMapper;
import com.jhgsys.internal.system.service.IRoleService;
import com.jhgsys.internal.system.service.IUserRoleService;
import com.jhgsys.internal.system.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author MrBird
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IDictService dictService;

    private String defaultPassword = User.DEFAULT_PASSWORD;
//
//    @Autowired
//    private ShiroRealm shiroRealm;

    @Override
    public User findByName(String username) {
        User user = this.baseMapper.findByName(username);
        if (user != null) {
            setUserRoles(user);
        }
        return user;
    }

    @Override
    public User findLeaderByDeptId(String deptId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeletedFlg, FebsConstant.VALID);
        queryWrapper.eq(User::getDeptLeaderFlg,"1");
        queryWrapper.eq(User::getDeptId,deptId);
        queryWrapper.last(" LIMIT 1 ");
        return this.baseMapper.selectOne(queryWrapper);
    }

    @Override
    public User findById(String userId) {
        User user = this.baseMapper.selectById(userId);
        if (user != null) {
            setUserRoles(user);
        }
        return user;
    }

    private void setUserRoles(User user) {
        List<Role> roles = this.roleService.findUserRole(user.getUserName());
        if (roles != null && roles.size() > 0) {
            user.setRoleId(roles.stream().map(r -> r.getRoleId()).collect(Collectors.joining(",")));
            user.setRoleName(roles.stream().map(Role::getRoleName).collect(Collectors.joining(",")));
        }
    }

    @Override
    public IPage<UserDto> findUserDetail(User user, QueryRequest request) {
        Page<User> page = new Page<>(request.getPageNum(), request.getPageSize());
        //SortUtil.handlePageSort(request, page, "deptId", FebsConstant.ORDER_DESC, true);
        //SortUtil.handlePageSort(request, page, "userId", FebsConstant.ORDER_ASC, true);
        return this.baseMapper.findUserDetailPage(page, user);
    }

    /**
     * 根据关键字搜索
     * @param user
     * @return
     */
    @Override
    public List<UserDto> findUserByKeywords(UserDto user) {
        return this.baseMapper.findUserByKeywords(user);
    }

    @Override
    public User findUserDetail(String username) {
        User param = new User();
        param.setUserName(username);
        List<User> users = this.baseMapper.findUserDetail(param);
        return CollectionUtils.isNotEmpty(users) ? users.get(0) : null;
    }

    @Override
    public User findUserDetailById(String userId) {
        return this.baseMapper.selectById(userId);
    }

    @Override
    @Transactional
    public void updateLoginTime(String username) {
        User user = new User();
        user.setLastLoginTime(new Date());
        this.baseMapper.update(user, new LambdaQueryWrapper<User>().eq(User::getUserName, username));
    }

    @Override
    @Transactional
    public void createUser(User user) {
        user.setCreateTime(new Date());
        user.setStatus(User.STATUS_VALID);
        user.setAvatar(User.DEFAULT_AVATAR);
        user.setTheme(User.THEME_WHITE);
        user.setIsTab(User.TAB_CLOSE);
        user.setPassword(MD5Util.encrypt(user.getUserName(), User.DEFAULT_PASSWORD));
        user.setPassword(MD5Util.encrypt(user.getUserName(), getDefaultPwd()));
        save(user);
        // 保存用户角色
        String[] roles = user.getRoleId().split(StringPool.COMMA);
        setUserRoles(user, roles);
    }


    @Override
    @Transactional
    public void deleteUsers(String[] userIds) {
        List<String> list = Arrays.asList(userIds);
        // 删除用户
        this.removeByIds(list);
        // 删除关联角色
        this.userRoleService.deleteUserRolesByUserId(list);
    }

    @Override
    @Transactional
    public void updateUser(User user) {
        // 更新用户
        user.setPassword(null);
    //    user.setUserName(user.getUserName());
        user.setModifyTime(new Date());
        updateById(user);
        // 更新关联角色
        this.userRoleService.remove(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, user.getUserId()));
        String[] roles = user.getRoleId().split(StringPool.COMMA);
        setUserRoles(user, roles);

//        User currentUser = FebsUtil.getCurrentUser();
//        if (StringUtils.equalsIgnoreCase(currentUser.getUsername(), user.getUsername())) {
//            shiroRealm.clearCache();
//        }
    }

    @Override
    @Transactional
    public void updateStatus(User user) {
        this.baseMapper.updateById(user);
    }

    @Override
    @Transactional
    public void resetPassword(String[] userIds) {
        Arrays.stream(userIds).forEach(userId -> {
            User user = new User();
            String username = this.baseMapper.selectById(userId).getUserName();
            user.setPassword(MD5Util.encrypt(username, getDefaultPwd()));
            this.baseMapper.update(user, new LambdaQueryWrapper<User>().eq(User::getUserId, userId));
        });
    }

    @Override
    @Transactional
    public void regist(String username, String password) {
        User user = new User();
        user.setPassword(MD5Util.encrypt(username, password));
        user.setUserName(username);
        user.setCreateTime(new Date());
        user.setStatus(User.STATUS_VALID);
        user.setSex(User.SEX_UNKNOW);
        user.setAvatar(User.DEFAULT_AVATAR);
        user.setTheme(User.THEME_BLACK);
        user.setIsTab(User.TAB_CLOSE);
        user.setDescription("注册用户");
        this.save(user);

        UserRole ur = new UserRole();
        ur.setUserId(String.valueOf(user.getUserId()));
        ur.setRoleId("2"); // 注册用户角色 ID
        this.userRoleService.save(ur);
    }

    @Override
    @Transactional
    public void updatePassword(String username, String password) {
        User user = new User();
        user.setPassword(MD5Util.encrypt(username, password));
        user.setModifyTime(new Date());
        this.baseMapper.update(user, new LambdaQueryWrapper<User>().eq(User::getUserName, username));
    }

    @Override
    @Transactional
    public void updateAvatar(String username, String avatar) {
        User user = new User();
        user.setAvatar(avatar);
        user.setModifyTime(new Date());
        this.baseMapper.update(user, new LambdaQueryWrapper<User>().eq(User::getUserName, username));
    }

    @Override
    @Transactional
    public void updateTheme(String username, String theme, String isTab) {
        User user = new User();
        user.setTheme(theme);
        user.setIsTab(isTab);
        user.setModifyTime(new Date());
        this.baseMapper.update(user, new LambdaQueryWrapper<User>().eq(User::getUserName, username));
    }

    @Override
    @Transactional
    public void updateProfile(User user) {
        user.setUserName(null);
        user.setRoleId(null);
        user.setPassword(null);
        updateById(user);
    }

    private void setUserRoles(User user, String[] roles) {
        List<UserRole> userRoles = new ArrayList<>();
        Arrays.stream(roles).forEach(roleId -> {
            UserRole ur = new UserRole();
            ur.setUserId(user.getUserId());
            ur.setRoleId(roleId);
            userRoles.add(ur);
        });
        userRoleService.saveBatch(userRoles);
    }

    @Override
    public void updateUserDeletedFlg(String[] ids, User user) {
        List<String> list = Arrays.asList(ids);
//        // 删除用户
//        for(int i=0;i<list.size();i++){
//            String userId = list.get(i);
//            User param = new User();
//            param.setDeleted_by(currentUserId);
//            param.setDeleted_time(new Date());
//            param.setDeleted_flg("1");
//            param.setUserId(Long.parseLong(userId));
//            this.baseMapper.updateUserDeletedFlg(param);
//        }
        this.baseMapper.update(user,new LambdaQueryWrapper<User>().in(User::getUserId,list));
        //this.baseMapper.update(user,new QueryWrapper<User>().lambda().in(User::getUserId,list));
        // this.removeByIds(list);
        // 删除关联角色
        this.userRoleService.deleteUserRolesByUserId(list);
    }

    /**
     * 根据角色名查询角色主键id
     * @author qiny
     * @since 2019-07-18
     * @param roleName
     * @return
     */
    @Override
    public Long findRoleIdByRoleName(String roleName) {
        List<Long> roles = this.baseMapper.findRoleIdByRoleName(roleName);
        return CollectionUtils.isNotEmpty(roles) ? roles.get(0) : null;
    }

    /**
     *
     * @param user
     * @param request
     * @return
     */
    @Override
    public IPage<User> findUserMail(User user, QueryRequest request){
        Page<User> page = new Page<>(request.getPageNum(), request.getPageSize());
        /*SortUtil.handlePageSort(request, page, "deptId", FebsConstant.ORDER_DESC, true);
        //SortUtil.handlePageSort(request, page, "userId", FebsConstant.ORDER_ASC, true);
        LambdaQueryWrapper<User> query = new LambdaQueryWrapper<User>();
        query.eq(User::getDeletedFlg, 0);
        if (StringUtils.isNotEmpty(user.getUsername())) {
            query.like(User::getUsername, user.getUsername());
        }
        if (StringUtils.isNotEmpty(user.getMobile())) {
            query.like(User::getMobile, user.getMobile());
        }
        if (user.getDeptId() != null) {
            query.eq(User::getDeptId, user.getDeptId());
        }*/
        return this.baseMapper.findUserMailList(page, user);
    }

    /**
     * 根据角色Id查询用户
     * @since 2019-07-18
     * @param roleId 角色Id
     * @param tenantId 租户Id
     * @return
     */
    @Override
    public List<User> findByRoleId(String roleId, String tenantId) {
        return this.baseMapper.findByRoleId(roleId,tenantId);
    }

    @Override
    public List<User> findUserByUserIds(List<String> userIds) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeletedFlg, FebsConstant.VALID);
        queryWrapper.in(User::getUserId, userIds);
        return this.baseMapper.selectList(queryWrapper);
    }
    /**
     * 查询（所有）
     * @author fenghaijun
     * @date 2024-07-19 13:53:31
     * @param user user
     * @return List<User>
     */
    @Override
    public List<User> findUserList(User user) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeletedFlg, 0);
        if(StringUtils.isNotBlank(user.getTenantId())){
            queryWrapper.eq(User::getTenantId, user.getTenantId());
        }
        if(StringUtils.isNotBlank(user.getUserName())){
            queryWrapper.eq(User::getUserName, user.getUserName());
        }
        if(StringUtils.isNotBlank(user.getDeptId())){
            queryWrapper.eq(User::getDeptId, user.getDeptId());
        }
        if(StringUtils.isNotBlank(user.getStatus())){
            queryWrapper.eq(User::getStatus, user.getStatus());
        }
        if(StringUtils.isNotBlank(user.getDeptLeaderFlg())){
            queryWrapper.eq(User::getDeptLeaderFlg, user.getDeptLeaderFlg());
        }
        if(StringUtils.isNotBlank(user.getContractorId())){
            queryWrapper.eq(User::getContractorId, user.getContractorId());
        }
        if(StringUtils.isNotBlank(user.getContractorTeamId())){
            queryWrapper.eq(User::getContractorTeamId, user.getContractorTeamId());
        }
        return this.baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<User> exportUsers(User user){
        return this.baseMapper.exportUsers(user);
    }

    /**
     * 获取默认用户密码
     * @date 2024-08-01 16:53:31
     * @return String
     */
    private String getDefaultPwd(){
        //初始化密码：默认查询字典，没有的话就取配置文件
        List<DictItem> dictItems = dictService.findDictByCode(DictCodeConstant.SYSTEM_DEFAULT_PASSWORD);
        if(CollectionUtils.isNotEmpty(dictItems)){
            defaultPassword = dictItems.get(0).getItemName();
        }
        return defaultPassword;
    }

    /**
     * 获取部门下的user
     * @author dinght
     * @date 2024-08-13 13:11:12
     */
    @Override
    public List<User> deptUserList(String deptId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeletedFlg, FebsConstant.VALID);
        queryWrapper.eq(User::getDeptId, deptId);
        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 更新用户积分
     * @param user
     * @return
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public boolean updateScore(User user) {
        return this.baseMapper.updateScore(user);
    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public boolean updateBatchScore(List<User> userList) {
        return this.baseMapper.updateBatchScore(userList);
    }

    @Override
   public   List<Map<String,String>>  getUserList(){
     return    this.baseMapper.getUserList();
    }
}
